package org.otarriinae.kaptcha.service.impl;


import com.google.code.kaptcha.impl.DefaultKaptcha;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.orarriinae.common.web.assertion.ServiceAssert;
import org.otarriinae.kaptcha.error.KaptchaError;
import org.otarriinae.kaptcha.error.KaptchaServiceException;
import org.otarriinae.kaptcha.modle.Kaptcha;
import org.otarriinae.kaptcha.service.KaptchaService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author xj
 * @since 1.0
 */
@Service
@Slf4j
public class KaptchaServiceImpl implements KaptchaService {

    private final RedisTemplate<String, String> redisTemplate;
    private final DefaultKaptcha defaultKaptcha;
    public static final String KEY = "kaptcha:verifCode:";

    public KaptchaServiceImpl(RedisTemplate<String, String> redisTemplate, DefaultKaptcha defaultKaptcha) {
        this.redisTemplate = redisTemplate;
        this.defaultKaptcha = defaultKaptcha;
    }


    /**
     * 获取验证码
     *
     * @param key 主键
     * @return Kaptcha 验证码信息
     */
    @Override
    public Kaptcha getKaptcha(String key) {
        if (StringUtils.isNotBlank(key)) {
            redisTemplate.delete(KEY + key);
        }
        String createText = defaultKaptcha.createText();
        BufferedImage image = defaultKaptcha.createImage(createText);
        String uuid = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(KEY + uuid, createText, 60, TimeUnit.SECONDS);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "jpg", outputStream);
        } catch (IOException e) {
            throw new KaptchaServiceException(KaptchaError.KAPTCHA_CREATE_ERROR);
        }

        return new Kaptcha(uuid, "data:image/jpg;base64," + Base64.getEncoder().encodeToString(outputStream.toByteArray()));
    }

    /**
     * 验证码校验
     *
     * @param key  主键
     * @param code 验证码
     */
    @Override
    public void validCode(String key, String code) {

        ServiceAssert.notEmpty(key, KaptchaServiceException.class, KaptchaError.KAPTCHA_IS_NOT_BLANK);
        ServiceAssert.notEmpty(code, KaptchaServiceException.class, KaptchaError.KAPTCHA_IS_NOT_BLANK);
        String redisCode = redisTemplate.opsForValue().get(KEY + key);
        ServiceAssert.notEmpty(redisCode, KaptchaServiceException.class, KaptchaError.KAPTCHA_NOT_FOUND);
        redisTemplate.delete(KEY + key);
        if (!redisCode.equals(code)) {
            throw new KaptchaServiceException(KaptchaError.KAPTCHA_IS_ERROR);
        }
    }
}
